<?php

namespace Book\Model;

use Think\Model;

class BookModel extends Model {
    public $git_user = 'pdosgk';


    public function new($info){

        $repos_name = $this->createGitRepositoryName($info);

        // $this->startTrans();//开启事务
        //创建仓库
        $this->gitCreateRepository($repos_name, $info);
        $info['repos_name'] = $repos_name;
        $bookid = $this->add($info);
        //生成默认章节
        $summary_content = '* [空白目录](default.md)';
        $chapter['filename'] = 'SUMMARY.md';
        $chapter['content'] = base64_encode($summary_content);

        //发布到Git
        $content_git = $this->gitCreateContent($repos_name, $chapter, '添加默认章节');
        //添加默认钩子
        

        if($content_git){
            //更新位置
            $update['ref'] = $content_git['commit']['sha'];
            $update['tree'] = $content_git['commit']['tree']['sha'];

            $this->where(['id' => $bookid])->save($update);
            $chapter['blob_sha'] = $content_git['content']['sha'];
            $chapter['sha'] = sha1($summary_content);
            $book_chapter_id = D('BookChapter')->CreateChapter($bookid, $chapter);
            return true;
        }else{
            return false;
        }
        //更新sha
        
        //添加到book_git表
        // $git_chapter = $chapter;
        // $git_chapter['sha'] = sha1($summary_content);
        // $git_chapter['bookid'] = $bookid;
        // D('book_git')->add($git_chapter);
        // $this->commit();
        // $this->rollback();//事务有错回滚

        return true;
    }

    public function deleteBook($namespace, $name){
        $map['namespace'] = $namespace;
        $map['name'] = $name;
        $detail = $this->where($map)->find();

        $this->startTrans();//开启事务
        //删除章节
        D('BookChapter')->where(['bookid' => $detail['id']])->delete();
        //删除发布
        D('BookRelease')->where(['bookid' => $detail['id']])->delete();
        M('book_chapter_release')->where(['bookid' => $detail['id']])->delete();
        //删除token
        M('book_token')->where(['bookid' => $detail['id']])->delete();
        //删除文章
        $this->where(['id' => $detail['id']])->delete();

        //删除git仓库
        $repos_name = $this->createGitRepositoryName($detail);
        $this->gitDeleteRepository($repos_name);
        //提交事务成功
        $this->commit();
        // $this->rollback();//事务有错回滚
    }

    public function saveSetting($bookid, $info){
        $this->where(['id' => $bookid])->save($info);
        return true;
    }


    public function createToken($bookid){
        $data['bookid'] = $bookid;
        $data['token'] = md5($bookid . time());
        $data['create_at'] = time();

        M('book_token')->add($data);
        return $data['token'];
    }

    public function getBook($namespace, $name){
        $map['namespace'] = $namespace;
        $map['name'] = $name;
        return $this->where($map)->find();
    }

    public function gitCreateRepository($repos_name, $info){
        $data['name'] = $repos_name;
        $data['description'] = $info['description'];

        $url = '/user/repos';
        $response_data = $this->getGitApi($url, [], 'post', $data);

        $response = json_decode($response_data, true);
        //创建成功返回仓库名称
        if($response['id'])
            return $response['name'];
        return false;
    }

    public function gitDeleteRepository($repos_name){
        $data['name'] = $repos_name;
        $data['description'] = $info['description'];

        ///repos/:owner/:repo
        $url = sprintf('/repos/%s/%s', C('GIT_OWNER'), $repos_name);
        $response = $this->getGitApi($url, [], 'delete', $data);
        return true;
    }

    public function gitGetASingleCommit($repos_name, $commit_sha){
        //GET /repos/:owner/:repo/commits/:commit_sha
        $url = sprintf('/repos/%s/%s/commits/%s', C('GIT_OWNER'), $repos_name, $commit_sha);
        $response_data = $this->getGitApi($url, [], 'get');
        $response = json_decode($response_data, true);
        var_dump($response);
        if(!$response['message'])
            return $response['files'];
        return true;
    }
    // Get a tree
    public function gitGetATree($repos_name, $tree_sha){
        //GET /repos/:owner/:repo/git/trees/:tree_sha
        $url = sprintf('/repos/%s/%s/git/trees/%s', C('GIT_OWNER'), $repos_name, $tree_sha);
        $response_data = $this->getGitApi($url, [], 'get');
        $response = json_decode($response_data, true);
        if(!$response['message'])
            return $response;
        else{
            var_dump($response);
        }
        return false;
    }

    public function gitGetABlob($repos_name, $file_sha){
        //GET /repos/:owner/:repo/git/blobs/:file_sha
        $url = sprintf('/repos/%s/%s/git/blobs/%s', C('GIT_OWNER'), $repos_name, $file_sha);
        $response_data = $this->getGitApi($url, [], 'get');
        $response = json_decode($response_data, true);
        if(!$response['message'])
            return $response['content'];
        else{
            var_dump($response);
        }
        return false;
    }

    public function gitCompareTwoCommits($repos_name, $now_ref, $ref){
        //GET /repos/:owner/:repo/compare/:base...:head
        $url = sprintf('/repos/%s/%s/compare/%s...%s', C('GIT_OWNER'), $repos_name, $now_ref, $ref);
        // $url = 'https://github.com/kancloud/book_pdosgk_test/compare/bded90338567edcd961a059fbf5c2b8cc10f7c17...c88ca6d3c988d6e73fd18f727005558fcd6d3103';
        $response_data = $this->getGitApi($url, [], 'get');
        // $header[] = 'Accept: application/vnd.github.v3.diff';
        // $content = getCurlData($url, [], 'get', [], 10, $header);
        $response = json_decode($response_data, true);
        // var_dump($content);exit;
        if(!$response['message'])
            return $response['files'];
        return true;
    }

    public function gitUpdateContent($repos_name, $data, $message = 'commit'){
        ///repos/用户名/仓库名/contents/文件路径
        $url = sprintf('/repos/%s/%s/contents/%s', C('GIT_OWNER'), $repos_name, $data['filename']);
        $data['message'] = $message;
        $data['content'] = $data['content'];
        $data['sha'] = $data['sha'];
        $response = $this->getGitApi($url, [], 'put', $data);
        return true;
    }

    public function gitCreateContent($repos_name, $data, $message = 'commit'){
        ///repos/用户名/仓库名/contents/文件路径
        $url = sprintf('/repos/%s/%s/contents/%s', C('GIT_OWNER'), $repos_name, $data['filename']);
        $data['message'] = $message;
        $data['content'] = $data['content'];
        $response_data = $this->getGitApi($url, [], 'put', $data);
        $response = json_decode($response_data, true);
        if($response['content'])
            return $response;
        return false;
    }

    public function gitCreateBlob($repos_name, $info){
        ///repos/:owner/:repo/git/blobs
        $url = sprintf('/repos/%s/%s/git/blobs', C('GIT_OWNER'), $repos_name);
        $data['content'] = $info['content'];
        $data['encoding'] = 'base64';

        // var_dump($data);exit;
        $response_data = $this->getGitApi($url, [], 'post', $data);
        $response = json_decode($response_data, true);
        if($response['sha']){
            return $response['sha'];
        }else{
            return false;
        }
    }

    public function gitCreateTree($repos_name, $trees){
        ////repos/:owner/:repo/git/trees
        $url = sprintf('/repos/%s/%s/git/trees', C('GIT_OWNER'), $repos_name);
        $data['tree'] = $trees;

        // var_dump($data);exit;
        $response_data = $this->getGitApi($url, [], 'post', $data);
        $response = json_decode($response_data, true);
        var_dump($response);
        if($response['sha']){
            return $response;
        }else{
            return false;
        }
    }

    public function gitCurrentCommit($repos_name){
        //GET repos/:owner/:repo/commits
        $url = sprintf('/repos/%s/%s/commits', C('GIT_OWNER'), $repos_name);

        // var_dump($data);exit;
        $response_data = $this->getGitApi($url, [], 'get');
        $response = json_decode($response_data, true);
        if(!empty($response)){
            return $response[0]['sha'];
        }else{
            return false;
        }
    }

    public function gitCreateCommit($repos_name, $tree_sha, $parents_commit_sha){
        ////repos/:owner/:repo/git/commits
        $url = sprintf('/repos/%s/%s/git/commits', C('GIT_OWNER'), $repos_name);
        $data['tree'] = $tree_sha;
        $data['message'] = 'update';
        $data['parents'][] = $parents_commit_sha;

        // var_dump($data);exit;
        $response_data = $this->getGitApi($url, [], 'post', $data);
        $response = json_decode($response_data, true);
        var_dump($response);
        if($response['sha']){
            return $response['sha'];
        }else{
            return false;
        }
    }

    public function gitUpdateReference($repos_name, $sha){
        //PATCH /repos/:owner/:repo/git/refs/:ref
        $url = sprintf('/repos/%s/%s/git/refs/%s', C('GIT_OWNER'), $repos_name, 'heads/master');
        $data['sha'] = $sha;
        // $data['force'] = true;

        // var_dump($data);exit;
        $response_data = $this->getGitApi($url, [], 'patch', $data);
        $response = json_decode($response_data, true);
        var_dump($response);
        if($response['sha']){
            return $response['sha'];
        }else{
            return false;
        }
    }

    public function gitCreateReference($repos_name, $sha){
        //POST /repos/:owner/:repo/git/refs
        $url = sprintf('/repos/%s/%s/git/refs', C('GIT_OWNER'), $repos_name);
        $data['sha'] = $sha;
        $data['ref'] = 'refs/heads/master';

        // var_dump($data);exit;
        $response_data = $this->getGitApi($url, [], 'post', $data);
        $response = json_decode($response_data, true);
        var_dump($response);
        if($response['sha']){
            return $response['sha'];
        }else{
            return false;
        }
    }

    public function createGitRepositoryName($info){
        return 'book_'.$info['namespace']. '_'.$info['name'];
    }

    //git功能测试
    public function getGitApi($url, $param = [], $type="get",$data=array(),$timeout = 10, $header = []){

        $url = 'https://api.github.com'.$url;
        // if($type != 'get'){
        //     //GIT_ACCESS_TOKEN需自行配置
        //     $header[] = 'Authorization: token '.C('GIT_ACCESS_TOKEN');
        // }
        $header[] = 'Authorization: token '.C('GIT_ACCESS_TOKEN');
        // var_dump($url);
        $content = getCurlData($url, $param, $type, $data, 10, $header);
        return $content;
    }
}

?>